import {
    // 第三方依赖
    load,
    he,

    // common中的属性
    UserAgentKey,
    randomUserAgent,
    randomPCUserAgent,
    randomMobileUserAgent,
    htmlToString,
    removeBasedOnSeparator,
    getPathFromUrl,
    checkEncoding,
    delayed,
    timeoutPromise,
    getBaseUrl,
    mySetTimeout,
    myClearTimeout,
    removeQuerySelector,
    Gender,
    GenderEnum,
    removeEmptyLines,
    removeLinesContaining,
    formatString,
    getAbsPath,

    // discover-class
    FilterCategory,
    FilterOption,
    FilterParameter,
    FilterCategoryType,
    DiscoverBook,
    BookLink,
    PageResult,
    DiscoverSource,

    // book-class
    BasicBook,
    Book,
    BasicChapter,
    SearchBookResult,
    BookSource,

    // 爬虫抽象class
    AbstractBookCrawler,
    BookCrawlerTest,
    AbstractDiscoverCrawler,
    DiscoverCrawlerTest,

    // request class
    RequestOptions,
    RequestType,
    RequestMethod,
    DeviceType,
    RequestResponse,
    RequestInputType,
    GetCookiesOptions,
} from './common.js'

/**
 * 发送请求
 * @param {String} url
 * @param {RequestOptions} options
 * @returns {RequestResponse} 返回response对象
 *
 */
async function request(url, options) {
    options = new RequestOptions(options ?? {});
    console.log("发送请求", url, options);

    return await timeoutPromise(options.timeout, new Promise(async (resolve, reject) => {
        for (let i = 0; i < options.retryCount; i++) {
            if (i !== 0) { // 只要不是第一次，则延时等待
                await delayed(5 * 1000); // 延时5秒
            }
            try {
                const requestResult = await callMethod('request', {
                    url,
                    ...options,
                });

                resolve(new RequestResponse({
                    url: requestResult.url,
                    status: requestResult.status,
                    text: async () => requestResult.text,
                    headers: requestResult.headers,
                    cookies: async () => requestResult.cookies,
                }));
            } catch (error) {
                console.log(`request error ${i + 1} ${error.message}`, error);
            }
        }
        reject(new Error(`Request error ... url: ${url}, options: ${JSON.stringify(options)}`));
    }));
}

function encodeUrl(inputString, encoding) {
    return callMethod('encodeUrl', {inputString, encoding});
}

/**
 *
 * @param {String} url
 * @param {GetCookiesOptions|null} options
 * @return {*}
 */
function getCookies(url, options) {
    options = new GetCookiesOptions(options ?? {});
    return callMethod('getCookies', {
        url,
        ...options
    });
}

window.myModule = {
    // 自身的属性
    request,
    encodeUrl,
    getCookies,

    // 第三方依赖
    load,
    he,

    // common中的属性
    UserAgentKey,
    randomUserAgent,
    randomPCUserAgent,
    randomMobileUserAgent,
    htmlToString,
    removeBasedOnSeparator,
    getPathFromUrl,
    checkEncoding,
    delayed,
    timeoutPromise,
    getBaseUrl,
    mySetTimeout,
    myClearTimeout,
    removeQuerySelector,
    Gender,
    GenderEnum,
    removeEmptyLines,
    removeLinesContaining,
    formatString,
    getAbsPath,

    // discover-class
    FilterCategory,
    FilterOption,
    FilterParameter,
    FilterCategoryType,
    DiscoverBook,
    BookLink,
    PageResult,
    DiscoverSource,

    // book-class
    BasicBook,
    Book,
    BasicChapter,
    SearchBookResult,
    BookSource,

    // 爬虫抽象class
    AbstractBookCrawler,
    BookCrawlerTest,
    AbstractDiscoverCrawler,
    DiscoverCrawlerTest,

    // request class
    RequestOptions,
    RequestType,
    RequestMethod,
    DeviceType,
    RequestResponse,
    RequestInputType,
    GetCookiesOptions,
};